function [ accVibAccu, gyroVibAccu, vibSectBgnIdx, vibSectEndIdx ] = vibdataproc_diff( IMUOut, accSF, gyroSF, dt ) %#codegen
%VIBDATAPROC_DIFF 惯组振动数据处理，采用振动/静止数据均值求差法
% IMUOut: 前三列为X、Y、Z加速度计输出，后三列为X、Y、Z陀螺输出
% dt: 采样周期，单位s

coder.extrinsic('plot', 'hold', 'rectangle', 'text', 'num2str', 'title');
SPS = round(1 / dt); % 每秒采样数（非整除时为近似值），每SPS个采样的时间长度称为准秒
% 按准秒计算惯组各通道输出脉冲数方差的和方根并根据其变化找出振动段的起止点
stdRSS = rss_cg(clusterstd(IMUOut, SPS), 2);
[stdRSSVibSectBgnIdx, stdRSSVibSectEndIdx, stdRSSVibSectNum] = findlargemagsects(stdRSS, 1, 2, 10, 5, 3); % 振动段前延长10准秒，后延长5准秒，忽略不超过3准秒的振动段
plot(stdRSS);
title('惯组各通道输出脉冲数方差的和方根');
hold('on');
for i=1:stdRSSVibSectNum(1, 1)
    rectangle('Position', [stdRSSVibSectBgnIdx(i, 1), 0, stdRSSVibSectEndIdx(i, 1)-stdRSSVibSectBgnIdx(i, 1), min(stdRSS)*10], 'EdgeColor', 'r');
    text(stdRSSVibSectBgnIdx(i, 1), min(stdRSS)*10, num2str(stdRSSVibSectBgnIdx(i, 1)));
    text(stdRSSVibSectEndIdx(i, 1), min(stdRSS)*10, num2str(stdRSSVibSectEndIdx(i, 1)));
end
hold('off');
% 将每准秒脉冲数方差和方根的振动段的起止点转换为脉冲数采样的起止点，进而转换为振动段各采样的序号
vibSectBgnIdx = coder.nullcopy(zeros(stdRSSVibSectNum(1, 1), 1));
vibSectEndIdx = coder.nullcopy(zeros(stdRSSVibSectNum(1, 1), 1));
for i=1:stdRSSVibSectNum(1, 1)
    vibSectBgnIdx(i, 1) = (stdRSSVibSectBgnIdx(i, 1)-1)*SPS + 1;
    vibSectEndIdx(i, 1) = min(stdRSSVibSectEndIdx(i, 1)*SPS, size(IMUOut, 1));
end
vibSectIdx = [];
coder.varsize('vibSectIdx', [Inf 1], [true false]);
for i=1:stdRSSVibSectNum(1, 1)
    vibSectIdx = vertcat(vibSectIdx, (vibSectBgnIdx(i, 1):vibSectEndIdx(i, 1))');
end
% 计算振动段和静止段输出脉冲数平均值
allSum = sum(IMUOut, 1);
vibSum = sum(IMUOut(vibSectIdx, :), 1);
statSum = allSum - vibSum;
allT = size(IMUOut, 1) * dt;
vibT = size(vibSectIdx, 1) * dt;
statT = allT - vibT;
statAvg = statSum / statT;
vibAvg = vibSum / vibT;
% 计算振动精度
avgDiff = vibAvg - statAvg;
accVibAccu = avgDiff(1, 1:3) ./ accSF';
gyroVibAccu = avgDiff(1, 4:6) ./ gyroSF';
end